﻿#include "pch.h"

#include "SvgFile.h"
#include "CSvgObjectService.h"
#include "SvgObjectHeaders.h"

#include <vector>
using  std::vector;

#import "msxml3.dll"
using namespace MSXML2;


CSvgFile::CSvgFile(void)
{
	allSvgObjects.clear();
}


CSvgFile::~CSvgFile(void)
{
	CSvgObject* pObj  =NULL;
	while (!allSvgObjects.empty()) {
		pObj = allSvgObjects.back();
		allSvgObjects.pop_back();
		if (pObj != NULL) {
			delete pObj;
			pObj == NULL;
		}
	}
}

void CSvgFile::CreateSvg()
{
	MSXML2::IXMLDOMDocumentPtr XMLDOC;
	MSXML2::IXMLDOMElementPtr XMLROOT;
	HRESULT mHR = XMLDOC.CreateInstance(_uuidof(MSXML2::DOMDocument30));
	if (mHR != S_OK) {
		MessageBox(NULL, _T("failed!!"), _T("提示"), MB_OK);
		return;
	}

	XMLROOT = XMLDOC->createElement("ROOT");
	XMLROOT->setAttribute("ID", "12345");  //设置根标签的属性;
	XMLDOC->appendChild(XMLROOT);
	CString TMP;
	MSXML2::IXMLDOMElementPtr XMLNODE;
	for (int I = 0; I < 10; I++)
	{
		TMP.Format(_T("%d"), I);
		CString csElement;
		csElement.Format(_T("NODE%s"), TMP);
		/*XMLNODE = XMLDOC->createElement((_bstr_t)("NODE"+TMP));*/
		XMLNODE = XMLDOC->createElement((_bstr_t)(csElement));
		XMLNODE->put_text((_bstr_t)"NODETEXTS");//设置标签的文本内容;
		XMLNODE->setAttribute("ID", (_variant_t)TMP);//设置标签的属性及内容;
		XMLNODE->setAttribute("NAME", "NODENAME");
		XMLROOT->appendChild(XMLNODE);
	}
	XMLDOC->save("XMLTEST.XML");
	XMLNODE.Release();
	XMLROOT.Release();
	XMLDOC.Release();
}

bool CSvgFile::LoadSvgFile(CString csSvgPath, CDC* pdc, CPoint ptStart)
{
	CSvgObjectService mCSvgObjectService;
	allSvgObjects.clear();

	MSXML2::IXMLDOMDocumentPtr XMLDOC;
	MSXML2::IXMLDOMElementPtr XMLROOT;
	MSXML2::IXMLDOMElementPtr XMLELEMENT;
	MSXML2::IXMLDOMNodeListPtr XMLNODES; //某个节点的所有子节点
	MSXML2::IXMLDOMNamedNodeMapPtr XMLNODEATTS;//某个节点的所有属性;
	MSXML2::IXMLDOMNodePtr XMLNODE;
	HRESULT mHR;
	mHR = XMLDOC.CreateInstance(_uuidof(MSXML2::DOMDocument30));
	if (mHR != S_OK) {
		MessageBox(NULL, _T("failed!!"), _T("提示"), MB_OK);
		return false;
	}

	CString csTempXml = csSvgPath.Left(csSvgPath.ReverseFind('.'));
	csTempXml += ".xml";
	CopyFile(csSvgPath, csTempXml, false);

	_variant_t var = (_variant_t)(LPCTSTR)csTempXml;
	VARIANT_BOOL ret = XMLDOC->load(var);
	if (ret != -1)
	{
		DeleteFile(csTempXml);
		MessageBox(NULL, _T("failed to Load file!!"), _T("提示"), MB_OK);
		return false;
	}
	XMLROOT = XMLDOC->GetdocumentElement();//获得根节点;
	mHR = XMLROOT->get_childNodes(&XMLNODES);//获得根节点的所有子节点;
	if (mHR != S_OK) {
		DeleteFile(csTempXml);
		MessageBox(NULL, _T(" XMLROOT: failed to get_childNodes!!"), _T("提示"), MB_OK);
		return false;
	}
	long XMLNODESNUM, ATTSNUM;
	mHR = XMLNODES->get_length(&XMLNODESNUM);//获得所有子节点的个数;
	if (mHR != S_OK) {
		DeleteFile(csTempXml);
		MessageBox(NULL, _T(" XMLNODES: failed to get_length!!"), _T("提示"), MB_OK);
		return false;
	}

	for (int I = 0; I < XMLNODESNUM; I++)
	{
		mHR = XMLNODES->get_item(I, &XMLNODE);//获得某个子节点;
		if (mHR != S_OK) {
			continue;
		}
		mHR = XMLNODE->get_attributes(&XMLNODEATTS);//获得某个节点的所有属性;
		if (mHR != S_OK) {
			continue;
		}
		mHR = XMLNODEATTS->get_length(&ATTSNUM);//获得某个节点所有属性的个数;
		if (mHR != S_OK) {
			continue;
		}

		CString csNodeName;
		csNodeName = (LPCSTR)XMLNODE->GetnodeName();//子节点的名字

		/////////////
		if (csNodeName.Compare(SVG_OBJECT_LINE) == 0)
		{
			CSvgLine* psvgLine = new CSvgLine(SVG_OBJECT_LINE);

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;//属性名称
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;//属性具体值

				if (T1.Compare(_T("x1")) == 0)
				{
					psvgLine->startX = StrToInt(T2) - ptStart.x;
				}
				if (T1.Compare(_T("y1")) == 0)
				{
					psvgLine->startY = StrToInt(T2) - ptStart.y;
				}
				if (T1.Compare(_T("x2")) == 0)
				{
					psvgLine->endX = StrToInt(T2) - ptStart.x;
				}
				if (T1.Compare(_T("y2")) == 0)
				{
					psvgLine->endY = StrToInt(T2) - ptStart.y;
				}
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgLine->stroke = T2;
					psvgLine->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgLine->strokeWidth = StrToInt(T2);
				}
			}
			mCSvgObjectService.DrawSvgLineToCDC(psvgLine, pdc, ptStart);
			allSvgObjects.push_back(psvgLine);
		}
		else if (csNodeName.Compare(SVG_OBJECT_CIRCLE) == 0)
		{
			CSvgCircle* psvgCircle=new CSvgCircle(SVG_OBJECT_CIRCLE);
			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;

				if (T1.Compare(_T("cx")) == 0)
				{
					psvgCircle->centerX = StrToInt(T2) - ptStart.x;
				}
				if (T1.Compare(_T("cy")) == 0)
				{
					psvgCircle->centerY = StrToInt(T2) - ptStart.y;
				}
				if (T1.Compare(_T("r")) == 0)
				{
					psvgCircle->radius = StrToInt(T2);
				}
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgCircle->stroke = T2;
					psvgCircle->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgCircle->strokeWidth = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgCircle->fill = T2;
					psvgCircle->fill.MakeLower();
				}
			}
			mCSvgObjectService.DrawSvgCircleToCDC(psvgCircle, pdc, ptStart);
			allSvgObjects.push_back(psvgCircle);

		}
		else if (csNodeName.Compare(SVG_OBJECT_RECT) == 0)//  矩形/圆角矩形
		{
			CSvgRect* psvgRect=new CSvgRect(SVG_OBJECT_RECT);
			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;

				if (T1.Compare(_T("x")) == 0)
				{
					psvgRect->leftX = StrToInt(T2) - ptStart.x;
				}
				if (T1.Compare(_T("y")) == 0)
				{
					psvgRect->topY = StrToInt(T2) - ptStart.y;
				}
				if (T1.Compare(_T("rx")) == 0)
				{
					psvgRect->rx = StrToInt(T2);
					psvgRect->isRoundedCorner = true;
				}
				if (T1.Compare(_T("ry")) == 0)
				{
					psvgRect->ry = StrToInt(T2);
				}
				if (T1.Compare(_T("width")) == 0)
				{
					psvgRect->width = StrToInt(T2);
				}
				if (T1.Compare(_T("height")) == 0)
				{
					psvgRect->height = StrToInt(T2);
				}

				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgRect->stroke = T2;
					psvgRect->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgRect->strokeWidth = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgRect->fill = T2;
					psvgRect->fill.MakeLower();
				}
			}
			mCSvgObjectService.DrawSvgRectToCDC(psvgRect, pdc, ptStart);
			allSvgObjects.push_back(psvgRect);
		}
		else if (csNodeName.Compare(SVG_OBJECT_ELLIPSE) == 0)
		{
			CSvgEllipse* psvgEllipse=new CSvgEllipse(SVG_OBJECT_ELLIPSE);

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;

				if (T1.Compare(_T("cx")) == 0)
				{
					psvgEllipse->cX = StrToInt(T2) - ptStart.x;
				}
				if (T1.Compare(_T("cy")) == 0)
				{
					psvgEllipse->cY = StrToInt(T2) - ptStart.y;
				}
				if (T1.Compare(_T("rx")) == 0)
				{
					psvgEllipse->rX = StrToInt(T2);
				}
				if (T1.Compare(_T("ry")) == 0)
				{
					psvgEllipse->rY = StrToInt(T2);
				}
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgEllipse->stroke = T2;
					psvgEllipse->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgEllipse->strokeWidth = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgEllipse->fill = T2;
					psvgEllipse->fill.MakeLower();
				}
			}
			mCSvgObjectService.DrawSvgEllipseToCDC(psvgEllipse, pdc, ptStart);
			allSvgObjects.push_back(psvgEllipse);
		}
		else if (csNodeName.Compare(SVG_OBJECT_POLYGON) == 0)
		{
			CSvgPolygon* psvgPolygon=new CSvgPolygon(SVG_OBJECT_POLYGON);

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;

				if (T1.Compare(_T("points")) == 0)
				{
					
					std::list<std::string> lst;
					std::string str;
					for (int i = 0; i < T2.GetLength(); i++)
					{
						if (T2.GetAt(i) != ' ')
						{
							str.push_back(T2.GetAt(i));//如果不为空，就存入
						}
						else if (!str.empty())//不为空，进入
						{
							lst.push_back(str);
							str.clear();
						}
					}
					if (!str.empty())
					{
						lst.push_back(str);
					}
					std::list<std::string>::iterator it = lst.begin();
					for (; it != lst.end(); it++)
					{
						CString strPoint;
						CPoint pt;
						for (int j = 0; j < it->size(); j++)
						{
							if (it->at(j) != ',')//不是逗号就存入
							{
								strPoint.AppendChar(it->at(j));
							}
							else if (!strPoint.IsEmpty())//strPoint判断为空则跳过，有值则进入
							{
								pt.x = StrToInt(strPoint) - ptStart.x;
								strPoint.Empty();
							}
						}
						if (!strPoint.IsEmpty())
						{
							pt.y = StrToInt(strPoint) - ptStart.y;
							strPoint.Empty();
						}
						psvgPolygon->points.push_back(pt);
					}
					lst.clear();
				}
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgPolygon->stroke = T2;
					psvgPolygon->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgPolygon->strokeWidth = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgPolygon->fill = T2;
					psvgPolygon->fill.MakeLower();
				}
			}
			mCSvgObjectService.DrawSvgPolygonToCDC(psvgPolygon, pdc, ptStart);
			allSvgObjects.push_back(psvgPolygon);
		}
		else if (csNodeName.Compare(SVG_OBJECT_POLYLINE) == 0)
		{
			CSvgPolyline* psvgPolyline=new CSvgPolyline(SVG_OBJECT_POLYLINE);

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;//存储数值

				if (T1.Compare(_T("points")) == 0)
				{
					std::list<std::string> lst;
					std::string str;
					for (int i = 0; i < T2.GetLength(); i++)
					{
						if (T2.GetAt(i) != ' ')
						{
							str.push_back(T2.GetAt(i));
						}
						else if (!str.empty())
						{
							lst.push_back(str);
							str.clear();
						}
					}
					if (!str.empty())
					{
						lst.push_back(str);
					}
					std::list<std::string>::iterator it = lst.begin();
					for (; it != lst.end(); it++)
					{
						CString strPoint;
						CPoint pt;
						for (int j = 0; j < it->size(); j++)
						{
							if (it->at(j) != ',')
							{
								strPoint.AppendChar(it->at(j));
							}
							else if (!strPoint.IsEmpty())
							{
								pt.x = StrToInt(strPoint) - ptStart.x;
								strPoint.Empty();
							}
						}
						if (!strPoint.IsEmpty())
						{
							pt.y = StrToInt(strPoint) - ptStart.y;
							strPoint.Empty();
						}
						psvgPolyline->points.push_back(pt);
					}
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgPolyline->fill = T2;
					psvgPolyline->fill.MakeLower();
				}

				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgPolyline->stroke = T2;
					psvgPolyline->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgPolyline->strokeWidth = StrToInt(T2);
				}
			}
			mCSvgObjectService.DrawSvgPolyLineToCDC(psvgPolyline, pdc, ptStart);
			allSvgObjects.push_back(psvgPolyline);
		}
		else if (csNodeName.Compare(SVG_OBJECT_TEXT) == 0)
		{
			CSvgText* psvgText=new CSvgText(SVG_OBJECT_TEXT);

			CString Text;
			Text = (char*)(_bstr_t)XMLNODE->Gettext();

			psvgText->transform.Empty();

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性;
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;

				psvgText->csText = Text;

				if (T1.Compare(_T("x")) == 0)
				{
					psvgText->x = StrToInt(T2) - ptStart.x;//图形位置-幕布位置

				}
				if (T1.Compare(_T("y")) == 0)
				{
					psvgText->y = StrToInt(T2) - ptStart.y;

				}
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgText->stroke = T2;
					psvgText->stroke.MakeLower();
				}
				if (T1.Compare(_T("font-size")) == 0)
				{
					psvgText->fontSize = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgText->fill = T2;
					psvgText->fill.MakeLower();
				}
				if (T1.Compare(_T("font-family")) == 0)
				{
					psvgText->fontType = T2;
				}
				if (T1.Compare(_T("width")) == 0)
				{
					psvgText->width = StrToInt(T2);
				}
				if (T1.Compare(_T("height")) == 0)
				{
					psvgText->height = StrToInt(T2);
				}
				if (T1.Compare(_T("transform")) == 0)
				{
					psvgText->transform = T2;
					CPoint pt;
					CString csContent;
					bool bStartLeft = false;
					for (int iCount = 0; iCount < T2.GetLength(); iCount++)
					{
						if (T2.GetAt(iCount) == '(')
						{
							bStartLeft = true;
						}
						if (T2.GetAt(iCount) == ')')
						{
							bStartLeft = false;
						}
						if (bStartLeft && T2.GetAt(iCount) != '(')
						{
							csContent.AppendChar(T2.GetAt(iCount));
						}
					}
					bool bContent = true;
					CString csTemp;
					std::vector<CString> vec;
					for (int iContentSize = 0; iContentSize < csContent.GetLength(); iContentSize++)
					{
						if (csContent.GetAt(iContentSize) != ' ')
						{
							csTemp.AppendChar(csContent.GetAt(iContentSize));
						}
						else if (!csTemp.IsEmpty())
						{
							vec.push_back(csTemp);
							csTemp.Empty();
						}
					}
					if (!csTemp.IsEmpty())
					{
						vec.push_back(csTemp);
						csTemp.Empty();
					}
					if (vec.size() == 3)
					{
						psvgText->iAngle = -10 * StrToInt(vec[0]);
						psvgText->transformPt.x = StrToInt(vec[1]) - ptStart.x;
						psvgText->transformPt.y = StrToInt(vec[2]) - ptStart.y;
					}
				}
			}
			mCSvgObjectService.DrawSvgTextToCDC(psvgText, pdc, ptStart);
			allSvgObjects.push_back(psvgText);
		}

		else if (csNodeName.Compare(SVG_OBJECT_PATH) == 0)
		{
			CSvgPath* psvgPath=new CSvgPath(SVG_OBJECT_PATH);

			for (int J = 0; J < ATTSNUM; J++)
			{
				mHR = XMLNODEATTS->get_item(J, &XMLNODE);//获得某个属性
				if (mHR != S_OK) {
					continue;
				}
				CString T1;
				T1 = (char*)(_bstr_t)XMLNODE->nodeName;
				CString T2;
				T2 = (char*)(_bstr_t)XMLNODE->text;



				if (T1.Compare(_T("d")) == 0)
				{
					psvgPath->d = T2;//d里面的内容在T2（cstring）

				}

				//
				if (T1.Compare(_T("stroke")) == 0)
				{
					psvgPath->stroke = T2;
					psvgPath->stroke.MakeLower();
				}
				if (T1.Compare(_T("stroke-width")) == 0)
				{
					psvgPath->strokeWidth = StrToInt(T2);
				}
				if (T1.Compare(_T("fill")) == 0)
				{
					psvgPath->fill = T2;
					psvgPath->fill.MakeLower();
				}
			}
			mCSvgObjectService.DrawSvgPathToCDC(psvgPath, pdc, ptStart);
			allSvgObjects.push_back(psvgPath);
		}

	}

	/////
	DeleteFile(csTempXml);

	XMLNODES.Release();
	XMLNODE.Release();
	XMLROOT.Release();
	XMLDOC.Release();

	return true;
}

	